
#pragma once

#undef CreateWindow
#undef DestroyWindow
#include "MainForm.h"

using namespace System::Collections::Generic;

namespace ttg_internal
{
	namespace utils
	{
		///<summary>
		/// Wrapper, that provides additional thread for GUI form (MainForm).
		///</summary>
		public ref class GuiThread abstract sealed
		{
			private:
				static MainForm ^_form;
				static System::Threading::AutoResetEvent ^_event;
				///<summary>
				/// Entry point for real GUI thread.
				/// It creates form.
				///</summary>
				static void GUIEntryPoint()
				{
					try
					{
						GuiThread::_form = gcnew MainForm();
						GuiThread::_event->Set();
						System::Windows::Forms::Application::Run(GuiThread::_form);
					}
					catch (System::Exception ^) { }
				}
			internal:
				static GuiThread()
				{
					_form = nullptr;
					_event = gcnew System::Threading::AutoResetEvent(false);
				}
				///<summary>
				/// Creates window (icon for tray).
				///</summary>
				static void CreateWindow()
				{
					//Checking.
					if (IsCreated())
						return;
					//Creating window.
					array<System::Threading::WaitHandle ^> ^handles
						= gcnew array<System::Threading::WaitHandle ^>(1);
					handles[0] = _event;
					System::Threading::Thread ^t
						= gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(GUIEntryPoint));
					t->Start();
					System::Threading::WaitHandle::WaitAny(handles);
				}
				///<summary>
				/// Destroyes window and hides tray icon.
				///</summary>
				static void DestroyWindow()
				{
					//Checking.
					if (!IsCreated())
						return;
					//Closing.
					_form->GetIcon()->Visible = false;
					_form->Close();
					_form = nullptr;
				}
				///<summary>
				/// Returns reference to form (or nullptr).
				///</summary>
				static MainForm ^GetForm()
				{ return _form; }
				///<summary>
				/// Returns true, if window is created.
				///</summary>
				static bool IsCreated()
				{ return GetForm() != nullptr; }
		};
	}
}
